/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package VISIE.characters;
import Basketball.Ball;
import VISIE.mathfunctions.Conversions;
import VISIE.models.AnimatedModel;
import VISIE.models.BasketballPlayerModel;
import VISIE.scenemanager.Court;
import VISIE.scenemanager.SceneCharacterManager;
import com.jme3.math.Vector3f;
import java.util.ArrayList;

/**
 *
 * @author Divesh
 */
public abstract class BasketballCharacter extends Character{
    
    public Ball ball;
    public boolean hasPossession;
    private BasketballTeam team;
    
    public abstract void doBallManipulation();

    public boolean isInPossession(){
        return hasPossession;
    }
    
    public void setBall(Ball b){
        ball = b;
        
        //sets ball for the agent planner
        if(this instanceof VISIE.characters.BasketballAgent){
            BasketballAgent ba = (BasketballAgent)this;
            ba.planner.setBall(b);
        }
    }
    
    public void setPossession(){
        hasPossession = true;
        ball.setPossession(this.getID());
    }
    
    public void removePossession(){
        System.out.println(this.getID() + " has removed possession");
        hasPossession = false;
    }    
    
    public Character getNearestCharacter(ArrayList<Character> candidates){
        float closestDist = 100000f;
        Character closestCharacter = null;
        for(int i = 0; i < candidates.size(); i++){
            if(this.getPosition().distance(candidates.get(i).getPosition()) < closestDist){
                closestCharacter = candidates.get(i);
                closestDist = this.getPosition().distance(closestCharacter.getPosition());
            }   
        }  
        return closestCharacter;
    }
    
    public boolean isShooting(){
        return characterModel.getCurrentAnimation(1).equals("shootAction");        
    }
    
    public boolean isPassing(){
        return characterModel.getCurrentAnimation(1).equals("passAction");
    }
    
    
    public boolean canSeeCharacter(Character c){
        if(this instanceof VISIE.characters.Player){
            Player p  = (Player)this;
            return p.isInPerceivedVision(c);
        }
        else if(this instanceof VISIE.characters.BasketballAgent){
            BasketballAgent ba = (BasketballAgent)this;
            return ba.perception.canSeeCharacter(c);
        }
        else{
            return false;
        }
    }
    
    public void setTeam(BasketballTeam t){
        team = t;
    }
    
    public int getTeamID(){
        if(team == null){
            return -1;
        }
        return team.getTeamID();
    }
    
    public boolean playerIsTeamMate(BasketballCharacter bc){//WILL RETURN TRUE IF COMPARING SAME CHARACTER
        return bc.getTeamID() == this.getTeamID();    
    }
    
    public ArrayList<BasketballCharacter> getTeamMates(){
        ArrayList<Character> c = SceneCharacterManager.getCharacterArray();
        ArrayList<BasketballCharacter> members = new ArrayList<BasketballCharacter>();
        for(int i = 0; i < c.size(); i++){
            BasketballCharacter bc = (BasketballCharacter)c.get(i);
            if(bc.getTeamID() == this.getTeamID() && bc.getID() != this.getID()){
                members.add(bc);
            }
        }
        return members;
    }
    
   public ArrayList<BasketballCharacter> getOpponents(){
        ArrayList<Character> c = SceneCharacterManager.getCharacterArray();
        ArrayList<BasketballCharacter> members = new ArrayList<BasketballCharacter>();
        for(int i = 0; i < c.size(); i++){
            BasketballCharacter bc = (BasketballCharacter)c.get(i);
            if(bc.getTeamID() != this.getTeamID()){
                members.add(bc);
            }
        }
        return members;
       
   }
   
   public ArrayList<BasketballCharacter> getAllOtherCharacters(){
        ArrayList<Character> c = SceneCharacterManager.getCharacterArray();
        ArrayList<BasketballCharacter> members = new ArrayList<BasketballCharacter>();
        for(int i = 0; i < c.size(); i++){
            BasketballCharacter bc = (BasketballCharacter)c.get(i);
            if(bc.getID() != this.getID()){
                members.add(bc);
            }
        }
        return members;
   }
    
    public Vector3f get2DPosition(){
        return this.getPosition().setY(0);    
    }
    
    public void makePlayerTransparent(){
        BasketballPlayerModel bm = (BasketballPlayerModel)characterModel;
        bm.setTransparency(0.3f);
    }
    
    public void cleanUp(){
        if(this.hasPossession){
            this.removePossession();
        }
    }
    
    public boolean canShoot(){
        
        Vector3f ballPos = ball.getBallPosition().setY(0);
        Vector3f goalPos = new Vector3f(Court.getHoopLocation().x, 0, Court.getHoopLocation().z);
        float dist = ballPos.distance(goalPos);
        
        if(dist < 5){
            return false;
        }
        else if(dist > 45){
            return false;
        }
        
        float threshold = 20;
        float angleToGoal = Conversions.originToTargetAngle(this.get2DPosition(), goalPos); 
        return Conversions.minDistanceBetweenAngles(this.getFacingDirection(), angleToGoal) < threshold;
     
    }
    
    public boolean canPass(BasketballCharacter target){
        float maxDistance = 20;
        return this.get2DPosition().distance(target.get2DPosition()) < maxDistance;
    }
    
    public boolean canSeeBall(Ball b){
        float angleBetween = Conversions.originToTargetAngle(this.getPosition(), b.getBallPosition());
        float f = Conversions.minDistanceBetweenAngles(angleBetween, this.getFacingDirection());
        return f < 60;                       
    }
}
